﻿using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace LuDragon.Common.Extensions
{   
    public static class IQueryableExtension
    {
        /// <summary>
        /// 排序
        /// </summary>
        /// <typeparam name="T">查询结果项类型</typeparam>
        /// <param name="query">列表对象</param>
        /// <param name="sort">排序字段</param>
        /// <param name="order">排序方式：ASC，DESC; 默认 ASC</param>
        /// <returns></returns>
        public static  IQueryable<T> Order<T>(this IQueryable<T> query, string sort, string order)
        {
            //如果排序字段为空则直接返回
            if (string.IsNullOrEmpty(sort))
                return query;

            PropertyInfo sortProperty = typeof(T).GetProperty(sort, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
            if (sortProperty == null)
                throw new Exception("查询对象中不存在排序字段" + sort + "！");

            ParameterExpression param = Expression.Parameter(typeof(T), "t");
            Expression body = param;
            if (Nullable.GetUnderlyingType(body.Type) != null)
                body = Expression.Property(body, "Value");
            body = Expression.MakeMemberAccess(body, sortProperty);
            LambdaExpression keySelectorLambda = Expression.Lambda(body, param);

            if (string.IsNullOrEmpty(order))
                order = "ASC";
            string queryMethod = order.ToUpper() == "DESC" ? "OrderByDescending" : "OrderBy";
            query = query.Provider.CreateQuery<T>(
                Expression.Call(typeof(Queryable),
                queryMethod,
                new Type[] { typeof(T), body.Type },
                query.Expression,
                Expression.Quote(keySelectorLambda)));
            return query;
        }
    }
}